<template>
  <div class="wik-table">
    <div class="wik-table-scroll" ref="tableScrollRef">
      <div class="wik-table-header-wrapper" :class="{ 'wik-table-fixed': headerFixed, 'wik-table-header-setting': minWidth }">
        <div
          class="wik-table-header"
          :style="`grid-template-columns:${columns
            .map((item: TableColumn) => widthLength(item.width, minWidth))
            .join(' ')} ${settingStyle}; `"
        >
          <div
            :class="{
              'wik-table-sticky': item.isFixed ?? excludeFields.includes(item.type),
              ...classNameExpand(item.className)
            }"
            class="wik-table-header-item"
            v-for="(item, index) in columns"
            :key="index"
          >
            <div class="wik-table-selection" v-if="item.type === 'selection'">
              <el-checkbox size="default" />
            </div>
            <span v-else class="wik-table-header-item-title" @click="() => (item.isShowSort ? sortHandler(item) : null)">
              <span class="wik-table-header-item-title-wrapper">
                <i> {{ item.title }}</i>
                <i v-if="item.isShowSort" class="wik-table-sort ml6">
                  <s class="triangle-up mb2" :class="{ 'triangle-up_active': item.sortType === SORT_ASC }"></s>
                  <s class="triangle-down" :class="{ 'triangle-down_active': item.sortType === SORT_DESC }"></s>
                </i>
              </span>
              <i class="resize" @click.stop @mousedown="e => mouseDownHandler(e, item)"></i>
              <TriggerContext
                v-if="setting.show && !excludeFields.includes(item.type)"
                class="point"
                :class="{ 'more-active': item.isMoreActive }"
                :component="ColumnMenu"
                :props="{ column: item }"
                @open="item.isMoreActive = true"
                @close="item.isMoreActive = false"
              >
                <s>...</s>
              </TriggerContext>
            </span>
          </div>
          <!-- 空余一行-->
          <div class="wik-table-header-item" v-if="setting.show"></div>
        </div>
      </div>
      <div class="wik-table-body" ref="tableBodyRef">
        <template v-if="tableDataUI && tableDataUI.length">
          <table-row
            :data="item"
            v-for="(item, index) in tableDataUI"
            :key="`${item.id}_${index}_table`"
            :layout="layout"
            :serial-number="index"
            ref="tableRowRef"
            @row-click="rowClickHandler"
            :style="virtual ? `top:${item.top}px;position:absolute` : ''"
          >
            <template v-for="slot in Object.keys(slots)" #[slot]="scope">
              <slot :name="slot" v-bind="scope"></slot>
            </template>
          </table-row>
        </template>
        <div v-else style="display: flex; align-items: center; justify-content: center; height: 100%"><el-empty></el-empty></div>
      </div>
    </div>
    <div class="wik-table-setting" v-if="setting.show">
      <SettingComponent />
    </div>
  </div>
</template>
<script setup lang="ts">
import { ref, useSlots, computed, onMounted, onUnmounted, unref, toRef, inject, watch } from "vue";
import SettingComponent from "@table/components/Setting/index.vue";
import ColumnMenu from "@table/components/ColumnMenu/index.vue";
import TableRow from "@table/components/TableRow.vue";
import TriggerContext from "@/components/TriggerContext/index.vue";

import { useUtils } from "@table/hooks/useUtils";
import { useColumn } from "@table/hooks/useColumn";
import { useData } from "@table/hooks/useData";
import { useSort } from "@table/hooks/useSort";
import { useFixedVirtual } from "@table/hooks/useFixedVirtual";
import { useTable } from "@table/hooks/useTable";
// import { useAutoVirtual } from "@table/hooks/useAutoVirtual";
import { widthLength, classNameExpand } from "@table/utils";
import { TableColumn, TableOptions } from "@table/interface";
import { excludeFields, SORT_DESC, SORT_ASC } from "@table/constant";

const { options, tableData, tableColumns: columns, tableScrollRef, doms, initTableColumns, originalTableColumns } = useData();
const { sortHandler } = useSort();
const { fixedStyle } = useColumn();
const { mouseDownHandler } = useUtils();
useTable();

const tableBodyRef = ref();
const layout = ref(1); // 层级
const slots = useSlots();
const eventBus: any = inject("eventBus");
let tableDataUI: any = [];

const { headerFixed, minWidth, setting, virtual } = unref<TableOptions>(options);

const settingStyle = computed(() => {
  return setting.show ? `minmax(${widthLength(undefined, minWidth)}, 1fr)` : "";
});

// definedEmits
const emits = defineEmits(["rowClick"]);

// 虚拟滚动
if (virtual) {
  if (virtual.type === "fix") {
    const { fixedVirtualData } = useFixedVirtual({
      wrap: tableScrollRef,
      contain: tableBodyRef,
      data: tableData,
      ...virtual.options
    });
    tableDataUI = toRef(fixedVirtualData);
  } else {
    // const { autoVirtualData } = useAutoVirtual({
    //   wrap: tableScrollRef,
    //   data: tableData,
    //   ...virtual.options
    // });
    // tableDataUI = toRef(autoVirtualData);
  }
} else {
  tableDataUI = toRef(tableData);
}

// 方法

const rowClickHandler = (val: any) => {
  emits("rowClick", val);
};
/**
 * 固定元素滚动条变化样式变化
 */
const fixedStyleScrollY = e => {
  if (e.target.scrollLeft > 0) {
    doms["fixedDoms"].forEach((item: HTMLElement) => {
      item.classList.add("wik-table-column-left-shadow");
    });
  } else {
    doms["fixedDoms"].forEach((item: HTMLElement) => {
      item.classList.remove("wik-table-column-left-shadow");
    });
  }
};

eventBus.on("fixedStyle", fixedStyle);

watch(
  () => originalTableColumns.value,
  () => {
    initTableColumns();
    fixedStyle();
  },
  { immediate: true }
);

onUnmounted(() => {
  tableScrollRef.value?.removeEventListener("scroll", fixedStyleScrollY);
  eventBus.off("fixedStyle", fixedStyle);
});
onMounted(() => {
  // y轴滚动条 固定元素样式变化
  tableScrollRef.value.addEventListener("scroll", fixedStyleScrollY);
});
</script>
<style lang="scss">
@use "@table/styles/index" as *;
.wik-table {
  position: relative;
  display: flex;
  flex-flow: column nowrap;
  width: 100%;
  height: 100%;
  overflow: hidden;
  &-fixed {
    position: sticky;
    top: 0;
    z-index: $wik-header-z-index;
  }
}
.wik-table-scroll {
  min-height: 100%;
  overflow: auto;
}
.wik-table-setting {
  position: absolute;
  top: 0;
  right: 0;
  z-index: 1002;
}
.wik-table-header-wrapper {
  width: 100%;
  background: var(--el-fill-color-light);
}
.wik-table-header {
  // position: relative;
  box-sizing: border-box;
  display: grid;
  flex: 0 0 45px;
  width: 100%;
  line-height: 45px;
  text-align: center;
  background: var(--el-fill-color-light);
  &-item {
    box-sizing: border-box;
    display: grid;
    align-items: center;
    height: 100%;
    font-size: 14px;
    font-weight: 600;
    color: #333333;
    border: 1px solid #eeeeee;
    border-right: 0;
    &:last-child {
      border-right: 1px solid #eeeeee;
    }
    &-title {
      position: relative;
      cursor: pointer;
      &-wrapper {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 100%;
      }
      .wik-table-sort {
        display: flex;
        flex-flow: column nowrap;
      }
      .resize {
        position: absolute;
        top: 0;
        right: 0;
        z-index: 2;
        display: block;
        width: 3px;
        height: 100%;
        cursor: e-resize;
        content: "";
        background: transparent;

        // background: $primary-color;
        &:hover {
          background: $primary-color;
        }
      }
      .point {
        position: absolute;
        top: 2px;
        right: 10px;
        display: none;
        width: 16px;
        height: 100%;
        color: #666666;
        s {
          display: block;
          font-size: 12px;
          letter-spacing: 2px;
          user-select: none;
          transform: rotate(90deg);
        }
        &:hover {
          color: $primary-color;
        }
      }
      .more-active {
        display: block;
        color: $primary-color;
      }
      &:hover {
        background: #fafafa;
        .point {
          display: block;
        }
      }
    }
  }
}
.wik-table-header-setting {
  min-width: max-content;
}
.wik-table-body {
  position: relative;
  width: 100%;
}
</style>
